package com.ayf.payment.game.api.controller.paychannel;

import com.alibaba.fastjson.JSONObject;
import com.ayf.payment.game.api.channel.jiabei.util.JbStringUtil;
import com.ayf.payment.game.api.entity.Order;
import com.ayf.payment.game.api.type.OrderStatus;
import com.ayf.payment.game.api.utils.DateUtils;
import com.ayf.payment.game.api.utils.HttpServletRequestUtil;
import com.ayf.payment.game.api.utils.Md5Utils;
import com.ayf.payment.game.api.utils.SnowFlakeUtils;
import com.ayf.payment.game.api.wx.WxSendMsgUtils;
import com.swwx.charm.commons.lang.utils.LogPortal;
import com.swwx.charm.zookeeper.exception.GetLockFailedException;
import com.swwx.charm.zookeeper.exception.ReleaseLockFailedException;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;


@RequestMapping("/v/qiyi/pay")
@RestController
public class QiYiPayNotifyController extends BasePayNotifyController {

    @Autowired
    private WxSendMsgUtils wxSendMsgUtils;

    @RequestMapping("/notify")
    public void notify(HttpServletRequest request, HttpServletResponse response) {
        String orderno = JbStringUtil.formatString(request.getParameter("order_id"));
        super.notifyAsync(request, response, orderno);
    }

    @RequestMapping("/returns")
    public void returns(HttpServletRequest request, HttpServletResponse response) {
        String orderno = JbStringUtil.formatString(request.getParameter("order_id"));
        super.notifySync(request, response, orderno);
    }

    /**
     * 代付异步通知处理
     */
    @RequestMapping("/paynotify")
    public void payNotify(HttpServletRequest request, HttpServletResponse response) {
        String orderno = JbStringUtil.formatString(request.getParameter("order_id"));
        super.agentPayNotifyAsync(request,response,orderno);
    }

    @Override
    protected void notifyAsyncBusinesExec(HttpServletRequest request, HttpServletResponse response,Object obj) {
        PrintWriter pw = null;
        String traceId = SnowFlakeUtils.getTraceId();
        try {
            pw = response.getWriter();
            //获取参数
            String status = JbStringUtil.formatString(request.getParameter("status"));
            String charset = JbStringUtil.formatString(request.getParameter("charset"));
            String user_id = JbStringUtil.formatString(request.getParameter("user_id"));
            String orderno = JbStringUtil.formatString(request.getParameter("order_id"));
            String pay_order_id = JbStringUtil.formatString(request.getParameter("pay_order_id"));
            String total_fee = JbStringUtil.formatString(request.getParameter("total_fee"));
            String attach = JbStringUtil.formatString(request.getParameter("attach"));
            String complete_date = JbStringUtil.formatString(request.getParameter("complete_date"));
            String sign = JbStringUtil.formatString(request.getParameter("sign"));
            LogPortal.info("{} 奇易交易异步通知 参数：status[{}] charset[{}] user_id[{}] orderno[{}] pay_order_id[{}] total_fee[{}] attach[{}] complete_date[{}] sign[{}]", traceId, status, charset, user_id, orderno, pay_order_id, total_fee, attach, complete_date, sign);
            if (StringUtils.isEmpty(orderno)) {
                LogPortal.info("{} 奇易交易异步通知 商户订单号数值为空，不进行后续操作", traceId);
                return;
            }
            Order order = orderService.selectByMerchantOrderNo(orderno);
            if (order == null) {
                LogPortal.error("{} 奇易交易异步通知 订单号[{}]在我方系统查询不到", traceId, orderno);
                return;
            }
            String KeyValue = systemInitialization.channelDTO(order.getPayChannleId()).getChannelKey();
            Map<String, Object> dicMap = new HashMap<>();
            dicMap.put("status", status);
            dicMap.put("charset", charset);
            dicMap.put("user_id", user_id);
            dicMap.put("order_id", orderno);
            dicMap.put("total_fee", total_fee);
            dicMap.put("pay_order_id", pay_order_id);
            dicMap.put("attach", attach);
            dicMap.put("complete_date", complete_date);
            Map<String, Object> sortByKey = sortByKey(dicMap);
            Set<String> keySet = sortByKey.keySet();
            StringBuilder str = new StringBuilder();
            for (String key : keySet) {
                str.append(key).append("=").append(sortByKey.get(key)).append("&");
            }
            String str2 = str.substring(0, str.length() - 1);
            String str3 = str2 + KeyValue;
            String signVer = Md5Utils.md5LowerCase(str3);
            if (!sign.equals(signVer)) {
                LogPortal.error("{} 奇易交易异步通知 商户订单号[{}] 异步通知验签失败", traceId, orderno);
                return;
            }
            if (!"1".equals(status)) {
                LogPortal.error("{} 奇易交易异步通知 状态未知 为：{}，不做处理。", traceId, status);
                return;
            }
            if (OrderStatus.PROCESSING.equals(order.getOrderStatus())) {
                String XY_GAME_PAY_LOCK_FLAG = System.getenv("XY_GAME_PAY_LOCK_FLAG");
                String orderLockName = "orderLock".concat(this.getClass().getSimpleName()).concat(XY_GAME_PAY_LOCK_FLAG).concat(orderno);
                boolean orderLock = false;
                try {
                    if (orderLock = distributedLock.getLock(orderLockName)) {
                        Order order2 = orderService.selectByMerchantOrderNo(orderno);
                        if (order2 != null && OrderStatus.PROCESSING.equals(order2.getOrderStatus())) {
                            order.setOrderNo(pay_order_id);
                            order.setOrderStatus(OrderStatus.SUCCESS);
                            order.setFinishTime(DateUtils.str2DateByFormat(complete_date,"yyyyMMddHHmmss"));
                            orderService.paymentOrder(order, new JSONObject());
                            if (OrderStatus.SUCCESS.equals(order.getOrderStatus())) {
                                orderService.orderToGetWay(order);
                                try {
                                    wxSendMsgUtils.rechargeSuccess(order);
                                } catch (Exception e) {
                                    LogPortal.error("{} 奇易交易异步通知 商户订单号[{}]CallBack 微信通知异常", e, traceId, orderno);
                                }
                            }
                        }
                    }
                } catch (GetLockFailedException e) {
                    LogPortal.error("{} >>> [DISTRIBUTED_LOCK_ACQUIRE_FAILED_ZK] 分布式锁获取失败,锁名称为:{}", orderno, orderLockName);
                    LogPortal.error("{} >>> {} 获取lock失败", e, orderno, orderLockName);
                } catch (Exception e) {
                    LogPortal.error("{} >>> {} 任务执行出错 ", e, orderno, orderLockName);
                } finally {
                    if (orderLock) {
                        LogPortal.info(orderno + " >>> " + orderLockName + " finished.");
                        try {
                            distributedLock.releaseLock(orderLockName);
                        } catch (ReleaseLockFailedException e) {
                            LogPortal.error("{} >>> [DISTRIBUTED_LOCK_RELEASE_FAILED_ZK] 分布式锁释放失败,锁名称为:{}", orderno, orderLockName);
                            LogPortal.error("{} >>> {} 释放失败", e, orderno, orderLockName);
                        }
                    }
                }
            } else {
                LogPortal.info("{} 奇易交易异步通知 商户订单号[{}] 订单库里状态不是处理中，不再更新订单状态：[{}]", traceId, orderno, order.getOrderStatus());
            }
        } catch (Exception e) {
            LogPortal.error("{} 奇易交易异步通知 验签业务逻辑处理失败，具体原因:{}", e, traceId, e.getMessage());
        } finally {
            pw.write("success");
            pw.flush();
            if (pw != null)
                pw.close();
        }
    }

    private static Map<String, Object> sortByKey(Map<String, Object> map) {
        Map<String, Object> treeMap = new TreeMap<>(String::compareTo);
        treeMap.putAll(map);
        return treeMap;
    }

    @Override
    protected void notifySyncBusinesExec(HttpServletRequest request, HttpServletResponse response) {
        String orderno = JbStringUtil.formatString(request.getParameter("order_id"));
        try {
            String attach = JbStringUtil.formatString(request.getParameter("attach"));
            response.sendRedirect(attach + "/gws/loading.html?orderNo=" + orderno);
        } catch (Exception e) {
            LogPortal.error("订单号:{} 奇易交易同步通知 发生{}异常",e,orderno,e.getClass().getName());
        }
    }

    @Override
    protected void agentPayNotifyAsyncBusinesExec(HttpServletRequest request, HttpServletResponse response, Object obj) {
        String traceId = SnowFlakeUtils.getTraceId();
        PrintWriter pw = null;
        try {
            pw = response.getWriter();
            Map<String, String> reqParmMap = HttpServletRequestUtil.getRequestParameters(request);
            LogPortal.info("{} 奇异代付异步通知 参数:{}", traceId,reqParmMap);
            String orderno = reqParmMap.get("order_id");
            if (StringUtils.isEmpty(orderno)){
                LogPortal.info("{} 奇异代付异步通知 商户订单号数值为空，不进行后续操作",traceId);
                return;
            }
            String status =reqParmMap.get("status");
            if (orderno.startsWith("Y")) {
                merchantCashOutService.QiYiPaymentOnBehalfOf(traceId, status, orderno);
            } else {
                merchantPayOrderService.QiYiPayNotify(traceId, status, orderno,reqParmMap.get("pay_order_id"));
            }
            pw.write("success");
            pw.flush();
        } catch (Exception e) {
            LogPortal.error("{} 奇异代付异步通知 业务逻辑处理失败，具体原因:{}", e, traceId, e.getMessage());
            pw.write("奇异代付异步通知 业务逻辑处理失败：" + e.getMessage());
            pw.flush();
        } finally {
            if (pw != null)
                pw.close();
        }
    }
}
